Houdiniメモ : 外周の厚みを一定にする
外周の厚みを一定にするVEXの紹介
https://gyazo.com/38cb2aa0778a2b542b18566198bd71ac
■考え方
外周の厚みを $ r 、 頂点の内角を $ 2 \theta としたとき、
ポイントを内側へ向かって $ \frac{r}{sin \theta } だけ動かすと一定の厚みの外周を作ることができます。
https://gyazo.com/88cedf5a5a4255e8028217d6bf139672
■ノード全体
https://gyazo.com/4976ddfa6538266fad65dbd660b198a5
■AttributeWrangle(1個目)
ベクトルの計算を行い、計算結果を v@MoveVector アトリビュートに保存します。
https://gyazo.com/1859df0d25a184aea4e4ea9ea6860724
code:calc(c)
int previousPt = (@ptnum - 1 + @numpt) % @numpt;
int currentPt = @ptnum;
int nextPt = (@ptnum + 1) % @numpt;
// 現在ポイントと直前ポイントまでの向きベクトル
vector previousDir = point(geoself(), "P", previousPt) - point(geoself(), "P", currentPt);
previousDir = normalize(previousDir);
// 現在ポイントと次のポイントまでの向きベクトル
vector nextDir = point(geoself(), "P", nextPt) - point(geoself(), "P", currentPt);
nextDir = normalize(nextDir);
// 2つのベクトルがなす角をもとめる(内角)
float radian = acos(dot(previousDir, nextDir));
// 中間ベクトル
vector centerDir = normalize(nextDir + previousDir);
// 頂点の内角が180°を超えると逆を向いてしまう対策
if (cross(nextDir, previousDir).y <= 0) {
centerDir = -centerDir;
}
// ベクトルの長さ
float r = chf("radius"); // 線の厚み
float vectorLength = r / sin(radian / 2.0);
// ポイントを動かすベクトルをアトリビュートへ保存
v@MoveVector = vectorLength * centerDir;
■AttributeWrangle(2個目)
v@MoveVector アトリビュートを使ってポイントを動かします。
https://gyazo.com/d5f9c17cd2a83e94a1fa63efd4a9288d
code:move_P(c)
@P += v@MoveVector;
■結果
移動結果のジオメトリと元のジオメトリをmergeすることで、一定の厚みを持った外周の完成です。
https://gyazo.com/c10c7c088b8943bb96828cf7f44384b0
関連
とあるデザイナーのテクニカルノート Houdini: 外周の厚みを一定にする